/**
 * 
 */
package com.iwords.service.ao.impl;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.ejb.EJB;
import javax.ejb.Stateless;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.iwords.constants.Constants;
import com.iwords.service.LearningStatusService;
import com.iwords.service.LearningStatusServiceLocal;
import com.iwords.service.object.KnownLevel;
import com.iwords.service.object.LearningStatusEntity;
import com.iwords.service.object.UserEntity;
import com.iwords.service.object.UserSysConfigEntity;
import com.iwords.service.persistence.LearningStatusPersistence;
import com.iwords.service.persistence.UserPersistence;

/**
 * @author       BOLIN.HBC 
 * @time         2011-4-5    
 * @description 单词操作的service       
 */
@Stateless
public class LearningStatusServiceImpl implements LearningStatusService, LearningStatusServiceLocal {

    @EJB
    LearningStatusPersistence learningStatusPersistence;
    @EJB
    UserPersistence userPersistence;
    private static final Log log = LogFactory.getLog(LearningStatusServiceImpl.class);

    public boolean moveSysLib(LearningStatusEntity entity) {
        /** 首先判断是不是已经有了这个课本 */
        if (!learningStatusPersistence.isExistUserLib(entity)) {

            learningStatusPersistence.moveSysLib(entity);
            return false;
        }
        return true;
    }

    public void changeStatus(LearningStatusEntity entity) {
        learningStatusPersistence.updateLearningStatus(entity);

    }

    public List<LearningStatusEntity> getStatusList(LearningStatusEntity entity) {
        return learningStatusPersistence.getStatusList(entity);

    }

    @SuppressWarnings("unchecked")
    public List<LearningStatusEntity> getFinalList(LearningStatusEntity entity) {
        try {
            return learningStatusPersistence.getFinalList(entity);
        } catch (Exception e) {
            log.error("获取用户最终状态的单词出错", e);

        }
        return Collections.EMPTY_LIST;
    }

    public boolean isExistUserLib(LearningStatusEntity entity) {
        return learningStatusPersistence.isExistUserLib(entity);
    }

    public Map<String, Integer> findAllLearningNumber(LearningStatusEntity entity) {

        // 获取当前课本里面的所有单词,并更新当前课本
        Long libid = entity.getLibid();
        UserEntity user = new UserEntity();
        user.setUserid(entity.getUserid());
        user.setCurrentlib(libid);
        userPersistence.updateCurrentLib(user);

        entity.setFamiliarity(null);//familiarity为空，返回全部的当前词库词汇列表
        List<LearningStatusEntity> currentList = getStatusList(entity);
        

        //查询全部当前lib的词汇列表，如果为空，则说明是新选择的词库，则做新选词库逻辑
        if (currentList == null || currentList.size() == 0) {
            this.moveSysLib(entity);
            currentList=getStatusList(entity);
        }

        entity.setLibid(null);
        // 1:获取所有学习过的单词  瓶颈现在在这里
        entity.setFamiliarity(KnownLevel.Known.getValue());
        
        long s1=System.currentTimeMillis();
        List<LearningStatusEntity> resultList = getFinalList(entity);
       System.out.println((System.currentTimeMillis()-s1)+"毫秒");
        List<LearningStatusEntity> finalList = new ArrayList<LearningStatusEntity>();

        Set<String> set = new HashSet<String>();

        for (int i = resultList.size() - 1; i >= 0; i--) {
            set.add(resultList.get(i).getWord().getSpelling());
        }
        for (String s : set) {
            for (LearningStatusEntity e : currentList) {
                //只对状态为0的做此处理
                if(e.getFamiliarity()==KnownLevel.None.getValue());{
                if (s.equals(e.getWord().getSpelling())) {
                    e.setFamiliarity(KnownLevel.Known.getValue());
                    finalList.add(e);
                }
            }
            }
        }
        Map<String, Integer> map = getCurrentLibMap(currentList, entity, libid);
        // 将背过的单词状态都置为最终状态 ，这就是词汇量
        for (LearningStatusEntity f : finalList) {
            if (learningStatusPersistence.getLearningStatusWord(f).getFamiliarity() != KnownLevel.Known.getValue()) {
                // 还不是熟悉,则将之更新成熟悉
                f.setFamiliarity(KnownLevel.Known.getValue());
                changeStatus(f);
            }
        }
        map.put("known_u", set.size());
        map.put("known_d", (map.get("known_d") == null ? 0 : map.get("known_d")));
        return map;
    }

    private int getBathchNumber(Long userid) {
        List<UserSysConfigEntity> configs = userPersistence.find(userid).getUserSysConfigs();
        int batch_number = Constants.USER_CONFIG_NUMBER;

        for (UserSysConfigEntity u : configs) {
            if (Constants.USER_CONFIG_NUMBER_KEY.equals(u.getConfigkey())) {
                batch_number = Integer.parseInt(u.getConfigvalue());

            }
        }
        return batch_number;

    }

    private Map<String, Integer> getCurrentLibMap(List<LearningStatusEntity> currentList, LearningStatusEntity entity, long libid) {

        Map<String, Integer> map = new HashMap<String, Integer>();
        int batch_number = getBathchNumber(entity.getUserid());

        map.put("batch_number", batch_number);
        map.put("unknown_u", 0);
        map.put("unknown_d", 0);
        map.put("level1_u", 0);
        map.put("level1_d", 0);
        map.put("level2_u", 0);
        map.put("level2_d", 0);
        map.put("level3_u", 0);
        map.put("level3_d", 0);
        map.put("level4_u", 0);
        map.put("level4_d", 0);
        map.put("level5_u", 0);
        map.put("level5_d", 0);
        map.put("known_u", 0);
        map.put("known_d", 0);
        for (LearningStatusEntity en : currentList) {

            switch (en.getFamiliarity()) {
                case 0:

                case 1:
                    // 0和1先不做区别,现在是全部放在上面的
                    initMap(map, KnownLevel.Unknown.getStr(), getWordType(en.getUpdatetime().getTime(), 0));
                    break;
                case 2:
                    initMap(map, KnownLevel.Level1.getStr(), getWordType(en.getUpdatetime().getTime(), KnownLevel.Level1.getRetainDays()));
                    break;
                case 3:
                    initMap(map, KnownLevel.Level2.getStr(), getWordType(en.getUpdatetime().getTime(), KnownLevel.Level2.getRetainDays()));

                    break;
                case 4:
                    initMap(map, KnownLevel.Level3.getStr(), getWordType(en.getUpdatetime().getTime(), KnownLevel.Level3.getRetainDays()));

                    break;
                case 5:
                    initMap(map, KnownLevel.Level4.getStr(), getWordType(en.getUpdatetime().getTime(), KnownLevel.Level4.getRetainDays()));

                    break;
                case 6:
                    initMap(map, KnownLevel.Level5.getStr(), getWordType(en.getUpdatetime().getTime(), KnownLevel.Level5.getRetainDays()));

                    break;
                case 7:
                    initMap(map, KnownLevel.Known.getStr(), getWordType(en.getUpdatetime().getTime(), KnownLevel.Known.getRetainDays()));
                    break;

            }
        }

        // 目前在0维度和1维度单词总数
        int number = map.get(KnownLevel.Unknown.getStr() + "_u") == null ? 0 : map.get(KnownLevel.Unknown.getStr() + "_u");

        //
        entity.setFamiliarity(KnownLevel.Unknown.getValue());
        // 今天上面可以学习的单词
        entity.setLibid(libid);
        int b = this.todayCanReadNumber(entity);

        // 表示当前还有可以学习的单词
        if (number != 0) {
            if (b >= number) {
                map.put(KnownLevel.Unknown.getStr() + "_u", number);
                map.put(KnownLevel.Unknown.getStr() + "_d", 0);
            } else {

                map.put(KnownLevel.Unknown.getStr() + "_u", b);
                map.put(KnownLevel.Unknown.getStr() + "_d", number - b);
            }

        }
        return map;

    }

    private int todayCanReadNumber(LearningStatusEntity entity) {

        List<LearningStatusEntity> currentList = new ArrayList<LearningStatusEntity>();
        // 维度为1的时候,只取维度为1的

        if (entity.getFamiliarity() == KnownLevel.Unknown.getValue()) {

            currentList.addAll(getStatusList(entity));
            //获取每天背单词的数目
            int batch_number = getBathchNumber(entity.getUserid());


            // 如果维度为1的一个都没有,那么就需要手动创造维度唯一的
            if (currentList.size() == 0) {

                entity.setFamiliarity(KnownLevel.None.getValue());
                List<LearningStatusEntity> noneList = getStatusList(entity);
                if (noneList == null || noneList.size() == 0) {
                    //代表没有学习的东西
                    return 0;
                }

                // 获取为0的,就是没有背诵过的
                entity.setFamiliarity(KnownLevel.None.getValue());
                currentList.addAll(getStatusList(entity));

                if (batch_number > currentList.size()) {
                    batch_number = currentList.size();
                }

                return batch_number;
            } else {

                // 今天置为1的都干掉
                int s = currentList.size();
                for (int i = currentList.size() - 1; i >= 0; i--) {
                    if (this.getWordType(currentList.get(i).getUpdatetime().getTime(), KnownLevel.Level1.getValue()) == 2) {
                        currentList.remove(i);
                    }
                }
                // 全是今天设置的1
                if (currentList.size() == 0) {
                    return s;
                } else {
                    // 今天还没有设置新的
                    if (s == currentList.size()) {

                        entity.setFamiliarity(KnownLevel.None.getValue());
                        currentList.addAll(getStatusList(entity));

                        if (batch_number > currentList.size()) {

                            return currentList.size();
                        } else {
                            return batch_number;
                        }
                    } else {
                        //除去剩余的全部返回
                        return s - currentList.size();
                    }
                }

            }
        }
        return 0;
    }

    private int getWordType(long dateTime, int day) {

        long s = System.currentTimeMillis() - dateTime;

        if ((s + 0.0) / (60 * 60 * 24 * 1000) >= day) {
            // 在上面,可以背诵
            return 1;
        }
        // 在下面,当前不能背诵
        return 2;

    }

    private void initMap(Map<String, Integer> map, String key, int type) {
        if (type == 1) {

            // 上面
            if (map.containsKey(key + "_u")) {
                map.put(key + "_u", map.get(key + "_u") + 1);
            } else {
                map.put(key + "_u", 1);
            }
        } else {
            // 下面
            if (map.containsKey(key + "_d")) {
                map.put(key + "_d", map.get(key + "_d") + 1);
            } else {
                map.put(key + "_d", 1);
            }
        }
    }

    public List<LearningStatusEntity> getLevelList(LearningStatusEntity entity) {

        List<LearningStatusEntity> currentList = new ArrayList<LearningStatusEntity>();
        // 维度为1的时候,只取维度为1的

        if (entity.getFamiliarity() == KnownLevel.Unknown.getValue()) {

            List<LearningStatusEntity> resultList = new ArrayList<LearningStatusEntity>();

            currentList.addAll(getStatusList(entity));
            int batch_number = getBathchNumber(entity.getUserid());

            // 如果维度为1的一个都没有,那么就需要手动创造维度唯一的
            if (currentList.size() == 0) {
                entity.setFamiliarity(KnownLevel.None.getValue());
                List<LearningStatusEntity> noneList = getStatusList(entity);
                if (noneList == null || noneList.size() == 0) {
                    //代表没有学习的东西
                    return currentList;
                }
                // 获取为0的,就是没有背诵过的

                currentList.addAll(getStatusList(entity));

                if (batch_number > currentList.size()) {
                    batch_number = currentList.size();
                }

                for (int i = 0; i < batch_number; i++) {
                    currentList.get(i).setFamiliarity(KnownLevel.Unknown.getValue());
                    this.changeStatus(currentList.get(i));
                    resultList.add(currentList.get(i));
                }

                currentList = resultList;
            } else {

                int size = currentList.size();
                List<LearningStatusEntity> deleteList = new ArrayList<LearningStatusEntity>();

                // 今天置为1的都干掉
                for (int i = currentList.size() - 1; i >= 0; i--) {
                    if (this.getWordType(currentList.get(i).getUpdatetime().getTime(), KnownLevel.Level1.getValue()) == 2) {
                        deleteList.add(currentList.get(i));
                        currentList.remove(i);
                    }
                }
                // 如果List里面一个都没有,那就证明拿出来的都是今天设置的List,那就将维度为1的全部返回给页面上
                if (deleteList.size() == size) {
                    return deleteList;
                } else {
                    // 证明今天还没有设置,那需要手动设置了,没有一个是今天的
                    if (size == currentList.size()) {
                        // 把状态为0的也算上
                        if (batch_number > currentList.size()) {
                            entity.setFamiliarity(KnownLevel.None.getValue());
                            currentList.addAll(getStatusList(entity));
                        }

                        if (currentList.size() < batch_number) {

                            batch_number = currentList.size();
                        }
                        for (int i = 0; i < batch_number; i++) {

                            currentList.get(i).setFamiliarity(KnownLevel.Unknown.getValue());
                            this.changeStatus(currentList.get(i));
                            resultList.add(currentList.get(i));

                        }
                        return resultList;

                    } else {
                        return deleteList;
                    }
                }
            }
        } else {
            currentList.addAll(getStatusList(entity));
            for (int i = currentList.size() - 1; i >= 0; i--) {

                int type = 0;

                switch (currentList.get(i).getFamiliarity()) {

                    case 2:
                        type = getWordType(currentList.get(i).getUpdatetime().getTime(), KnownLevel.Level1.getRetainDays());
                        break;
                    case 3:
                        type = getWordType(currentList.get(i).getUpdatetime().getTime(), KnownLevel.Level2.getRetainDays());
                        break;
                    case 4:
                        type = getWordType(currentList.get(i).getUpdatetime().getTime(), KnownLevel.Level3.getRetainDays());
                        break;
                    case 5:
                        type = getWordType(currentList.get(i).getUpdatetime().getTime(), KnownLevel.Level4.getRetainDays());
                        break;
                    case 6:
                        type = getWordType(currentList.get(i).getUpdatetime().getTime(), KnownLevel.Level5.getRetainDays());
                        break;
                    case 7:
                        type = getWordType(currentList.get(i).getUpdatetime().getTime(), KnownLevel.Level1.getRetainDays());

                        if (type == 2) {
                            type = 1;
                        } else {
                            type = 2;
                        }
                        break;

                }
                // 把下面的全部删除掉,如果是维度为7的话，只出现维度为7今天修改过的
                if (type == 2) {
                    currentList.remove(i);
                }
            }

        }
        return currentList;
    }
}